#include "fsm_evt.h"
#include "Bsp.h"

static uint8_t system_evt_pool[system_evt_pool_size] = {0};
struct evt_list_t  system_evt_node;

void evt_list_init(struct evt_list_t *l)
{
    l->next = l->prev = l;
}

void evt_list_insert(struct evt_list_t *n)
{
    struct evt_list_t *l = &system_evt_node;

    if (n == l)
    {
        return;
    }

    l->prev->next = n;
    n->prev = l->prev;

    l->prev = n;
    n->next = l;
}

struct evt_list_t *evt_list_remove(struct evt_list_t *n)
{
    struct evt_list_t *l = n->prev;

    if (n == &system_evt_node)
    {
        return n;
    }

    n->next->prev = n->prev;
    n->prev->next = n->next;

    n->next = n->prev = n;

    return l;
}

int evt_list_isempty(const struct evt_list_t *l)
{
    return l->next == l;
}

/*************************************  事件函数  *********************************/
void fsm_evt_init(struct evt_list_t *n, uint8_t *evt_pool, evt_func func, uint32_t evt_pool_size, uint8_t evt_sgl_size)
{
    // 断言，参数不能为空
    BSP_Assert(n);
    BSP_Assert(func);
    
    // 初始化链表
    evt_list_init(n);

    // 初始化 消息队列
    fsm_msg_init(&n->msg_ctr, evt_pool, evt_pool_size, evt_sgl_size);

    // 回调函数
    n->func = func;
}

int fsm_evt_write(struct evt_list_t *n, uint8_t *pData, uint8_t len)
{
    int ret = 0;
    
    BSP_Assert(n && n->next);
    
    // 写入消息
    ret = fsm_msg_write(&n->msg_ctr, pData, len);

    // 写入成功，如果链表为空 则加入任务链表
    if (ret && evt_list_isempty(n))
    {
        evt_list_insert(n);
    }
    
    return ret;
}

int fsm_evt_read(struct evt_list_t *n, uint8_t *pData)
{
    BSP_Assert(n && n->next);
    
    return fsm_msg_read(&n->msg_ctr, pData);
}

void fsm_system_evt_init(void)
{
    fsm_evt_init(&system_evt_node, system_evt_pool, fsm_system_evtfunc, system_evt_pool_size, system_evt_sgl_size);
}

int fsm_evt_tasks(void)
{
    struct evt_list_t *p = &system_evt_node;
    uint32_t status = 0;

    for ( ; ; p = p->next)
    {
        // 返回未处理事件数量
        status = (*p->func)(&p->msg_ctr);
        
			  // 处理事件完成
        if (status == 0)
        {
				    // 是否空闲列表
            if (evt_list_isempty(p))
            {
                fsm_system_idle();
            }
            else 
            {
                p = evt_list_remove(p);
            }
        }
    }
}
